import LayOptionVmodel from "./LayOptionVmodel.js";
import { logger, tools, runtime } from "./tools.js";


/**Layui复选框 */
class LayCheckBoxVmodel extends LayOptionVmodel {

    get value() {
        return this.element.value;
    }

    /**支持 tag|switch|primary */
    get skin() {
        return $(this.element).attr("lay-skin") || "primary";
    }

    constructor(elem) {
        super(elem);
        let tis = this;
        let vm = this.vm;
        this.checkFormFilter();
        this.ensureName();
        this.ensureFilter();
        // this.obs = tools.createElemObserver(elem, {
        //     attrChange: function (attr, newValue) {
        //         //console.log(attr, newValue);
        //         switch (attr) {
        //             case 'value': vm.value(newValue); break;
        //             case 'disabled': vm.disabled(!!newValue); break;
        //             case 'checked': vm.checked(!!newValue); break;
        //             case 'title': vm.title(newValue); break;
        //         }
        //     }
        // });
    }
    
    /**[override] */
    loadForAttr() {
        super.loadForAttr();
        let elem = this.element;
        let vm = this.vm;
        //初始化
        if ($(elem).val() !== void 0) {
            vm.value($(elem).val().toString());
        }        
        vm.checked($(elem).prop("checked"));
        vm.title($(elem).attr("title"));

        this.init(); //执行初始化       
    }

    /**[override] 初始化 */
    init() {
        if(!super.init()) return;
        if (!this.vm.value) {
            throw new Error("layCheckBox绑定元素必须有value属性");
        }
        let tis = this;
        let vm = this.vm;
        let form = tools.laymod("form");
        //绑定元素到vmodel
        form.on(`${tis.skin === "switch" ? "switch" : "checkbox"}(${this.layFilter})`, function (data) {
            var elem = data.elem; // 获得 checkbox 原始 DOM 对象
            var checked = elem.checked; // 获得 checkbox 选中状态
            vm.checked(checked);
        });

        let onchange = function (newValue) {
            tis.updateCheckBox();
        }

        //绑定vmodel到元素
        vm.value.subscribe(onchange, null, "change");        
        vm.title.subscribe(onchange, null, "change");
        vm.checked.subscribe(onchange, null, "change");

        this.updateCheckBox();

        this.inited = true;
    }
    
    updateCheckBox() {
        let tis = this;
        let vm = this.vm;

        //设置title
        $(tis.element).attr("title", vm.title());
        //设置选中状态
        let checked = vm.checked();
        $(tis.element).prop("checked", checked);
        //设置value
        $(tis.element).val(vm.value());

        $(tis.element).next().children("div").text(vm.title());
        $(tis.element).next().toggleClass("layui-form-checked", checked);
        if (tis.skin === "switch") {
            $(tis.element).next().toggleClass("layui-form-onswitch", checked);
        }
    }
}


/**Layui复选框 组管理器 */
class CheckedArrayAccessor {
    valueType = "string"; //默认的值类型
    vmodelList = []; //绑定的vmodel列表
    accessor = null; //ko数组
    id = null; //id

    constructor(id, accessor) {
        var tis = this;
        var accessorValue = ko.unwrap(accessor);
        if (!Array.isArray(accessorValue)) {
            throw new Error("CheckedArrayAccessor的accessor必须是ko数组");
        }

        this.accessor = accessor;
        this.id = id;

        //订阅数组变化
        accessor.subscribe(function (newValue) {
            tis._checkedUpdate();
        });
    }

    //检查数组并更新选中状态
    _checkedUpdate = function () {
        var nowValue = this.accessor().map(m => m.toString());

        this.vmodelList.forEach(function (vmodel) {
            var elmValue = vmodel.vm.value();
            var isContain = nowValue.indexOf(elmValue) > -1;
            vmodel.vm.checked(isContain);
        });
    };

    /**添加值,已存在则返回 */
    pushValue(value) {
        if (!this.checkValueType(value)) {
            throw new Error("CheckedArrayAccessor的value必须是" + this.valueType + "类型");
        }
        var nowValue = this.accessor().map(m => m.toString());
        if (nowValue.indexOf(value) > -1) {
            return;
        }
        this.accessor.push(value);
    }

    /**删除值 */
    removeValue(value) {
        if (!this.checkValueType(value)) {
            throw new Error("CheckedArrayAccessor的value必须是" + this.valueType + "类型");
        }
        //删除所有匹配的值
        var nowValue = this.accessor().map(m => m.toString());
        var index = nowValue.indexOf(value);
        while (index > -1) {
            this.accessor.splice(index, 1);
            nowValue = this.accessor().map(m => m.toString());
            index = nowValue.indexOf(value);
        }
    }


    /**检测value值类型*/
    checkValueType(value) {
        if (value === null || value === undefined) {
            return true;
        }
        let valueType = typeof value;
        if (valueType !== this.valueType) {
            return false;
        }
        return true;
    }

    /**
     * 添加checkbox模型 
     * @param {LayCheckBoxVmodel} vmodel 
     **/
    addLayCheckbox(vmodel) {
        if (!(vmodel instanceof LayCheckBoxVmodel)) {
            throw new Error("addLayCheckbox参数必须是LayCheckBoxVmodel");
        }
        if (this.vmodelList.find(m => m.eHashid === vmodel.eHashid)) {
            return;
        }
        let vm = vmodel.vm;
        let tis = this;
        let form = tools.laymod("form");
        
        //绑定元素到vmodel
        form.on(`checkbox(${vmodel.layFilter})`, function (data) {
            var elem = data.elem; // 获得 checkbox 原始 DOM 对象
            var checked = elem.checked; // 获得 checkbox 选中状态
            var value = elem.value; // 获得 checkbox 值
            if (checked) {
                tis.pushValue(value.toString());
            } else {
                tis.removeValue(value.toString());
            }
        });

        vm.checked.subscribe((newValue) => {
            let value = vmodel.value;
            vm.checked() ? tis.pushValue(value) : tis.removeValue(value);
        }, null, "change");

        this.vmodelList.push(vmodel);
        this._checkedUpdate();
    }
}

export { LayCheckBoxVmodel, CheckedArrayAccessor };